package com.settlement.system.controller;

import cn.hutool.core.util.StrUtil;
import com.settlement.system.common.enums.CostAllocationEnum;
import com.settlement.system.common.enums.InUseOrNotEnum;
import com.settlement.system.common.enums.ReturnStatusEnum;
import com.settlement.system.common.exception.ServiceException;
import com.settlement.system.model.entity.common.TblRrBillType;
import com.settlement.system.model.entity.common.TblRrRecordProjectMain;
import com.settlement.system.model.entity.common.TblRrVoucherType;
import com.settlement.system.reply.ObjectDataResponse;
import com.settlement.system.service.*;
import com.settlement.system.common.util.common.FasUtil;
import com.alibaba.excel.context.AnalysisContext;
import io.swagger.annotations.Api;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import javax.validation.constraints.Pattern;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static java.util.stream.Collectors.groupingBy;

/**
 * 收退款-记账项目主表 前端控制器
 *
 * @author Ximi
 * @since 2020-07-06
 */

@Slf4j
@Api(tags = "收退款-记账项目主表", description = "收退款-记账项目主表")
@RestController
@RequestMapping("/rr/record_project/main")
public class TblRrRecordProjectMainController extends ExcelController<TblRrRecordProjectMain> {

    @Resource
    private ITblRrRecordProjectMainService tblRrRecordProjectMainService;

    @Resource
    private ITblRrVoucherTypeService tblRrVoucherTypeService;

    @Resource
    private ITblRrChannelService tblRrChannelService;

    @Resource
    private ITblRrBillTypeService tblRrBillTypeService;

    @Override
    public IBaseService init() {
        return tblRrRecordProjectMainService;
    }

    @Override
    public Class<?> getModelClass() {
        return TblRrRecordProjectMain.class;
    }

    @Override
    protected void setParamsModel(Map<String, Object> model) {
        FasUtil.formatInQueryCondition(model, "recordAccountProject","billType");
        super.setParamsModel(model);
    }

    public String checkSaveModel(TblRrRecordProjectMain tblRrRecordProjectMain) {
        try {
            List<TblRrRecordProjectMain> tblRrRecordProjectMains = tblRrRecordProjectMainService.selectByParams(tblRrRecordProjectMain);
            if (!CollectionUtils.isEmpty(tblRrRecordProjectMains)) {
                return "数据已存在";
            } else {
                if (!StringUtils.isEmpty(tblRrRecordProjectMain.getVoucherType())) {
                    TblRrVoucherType voucherType = tblRrVoucherTypeService.getByVoucherType(tblRrRecordProjectMain.getVoucherType());
                    if (voucherType == null) {
                        return "凭证类型不正确:" + tblRrRecordProjectMain.getVoucherType();
                    }
                }

                Map<String, Object> map = new HashMap<>();
                map.put("billType", tblRrRecordProjectMain.getBillType());
                map.put("status", InUseOrNotEnum.YES.getNo());
                List<TblRrBillType> tblRrBillTypes = tblRrBillTypeService.selectByParam(map);
                if (CollectionUtils.isEmpty(tblRrBillTypes)) {
                    return "[账单类型]的值应该取自【RR-账单类型】";
                }

                map = new HashMap<>();
                map.put("billCategory", tblRrRecordProjectMain.getBillCategory());
                FasUtil.formatInQueryCondition(map, "billCategory");
                map.put("status", InUseOrNotEnum.YES.getNo());
                tblRrBillTypes = tblRrBillTypeService.selectByParam(map);
                if (CollectionUtils.isEmpty(tblRrBillTypes)) {
                    return "[账单大类]的值应该取自【RR-账单类型】";
                }

                map = new HashMap<>();
                map.put("recordAccountProject", tblRrRecordProjectMain.getRecordAccountProject());
                FasUtil.formatInQueryCondition(map, "recordAccountProject");
                List<TblRrRecordProjectMain> tblRrRecordProjectList = tblRrRecordProjectMainService.selectByParam(map);
                for (TblRrRecordProjectMain rrRecordProjectMain : tblRrRecordProjectList) {
                    //不相等，如果是新增或者更新时ID不相等
                    if (!tblRrRecordProjectMain.getNcMarketTool().equals(rrRecordProjectMain.getNcMarketTool())
                            && (StringUtils.isEmpty(tblRrRecordProjectMain.getId()) || (
                            StringUtils.isNotEmpty(tblRrRecordProjectMain.getId()) &&
                                    !tblRrRecordProjectMain.getId().equals(rrRecordProjectMain.getId())
                    ))) {
                        return "同个记账项目对应的[辅助项_营销工具]必须一致。";
                    }
                }
            }
        } catch (Exception e) {
            log.error("校验时查询出错", e);
            return "校验时查询出错";
        }
        return null;
    }

    public String checkUpdateModel(TblRrRecordProjectMain tblRrRecordProjectMain) {
        try {
            List<TblRrRecordProjectMain> tblRrRecordProjectMains = tblRrRecordProjectMainService.selectByParams(tblRrRecordProjectMain);
            if (!CollectionUtils.isEmpty(tblRrRecordProjectMains)) {
                for (TblRrRecordProjectMain rrRecordProjectMain : tblRrRecordProjectMains) {
                    if (!tblRrRecordProjectMain.getId().equals(rrRecordProjectMain.getId())) {
                        return "数据已存在";
                    }
                }
            }

            if (!StringUtils.isEmpty(tblRrRecordProjectMain.getVoucherType())) {
                TblRrVoucherType voucherType = tblRrVoucherTypeService.getByVoucherType(tblRrRecordProjectMain.getVoucherType());
                if (voucherType == null) {
                    return "凭证类型不正确:" + tblRrRecordProjectMain.getVoucherType();
                }
            }

            Map<String, Object> map = new HashMap<>();
            map.put("billType", tblRrRecordProjectMain.getBillType());
            map.put("status", InUseOrNotEnum.YES.getNo());
            List<TblRrBillType> tblRrBillTypes = tblRrBillTypeService.selectByParam(map);
            if (CollectionUtils.isEmpty(tblRrBillTypes)) {
                return "[账单类型]的值应该取自【RR-账单类型】";
            }

            map = new HashMap<>();
            map.put("billCategory", tblRrRecordProjectMain.getBillCategory());
            FasUtil.formatInQueryCondition(map, "billCategory");
            map.put("status", InUseOrNotEnum.YES.getNo());
            tblRrBillTypes = tblRrBillTypeService.selectByParam(map);
            if (CollectionUtils.isEmpty(tblRrBillTypes)) {
                return "[账单大类]的值应该取自【RR-账单类型】";
            }

            map = new HashMap<>();
            map.put("recordAccountProject", tblRrRecordProjectMain.getRecordAccountProject());
            FasUtil.formatInQueryCondition(map, "recordAccountProject");
            List<TblRrRecordProjectMain> tblRrRecordProjectList = tblRrRecordProjectMainService.selectByParam(map);
            for (TblRrRecordProjectMain rrRecordProjectMain : tblRrRecordProjectList) {
                //不相等，如果是新增或者更新时ID不相等的情况
                if (!tblRrRecordProjectMain.getNcMarketTool().equals(rrRecordProjectMain.getNcMarketTool())
                        && (StringUtils.isEmpty(tblRrRecordProjectMain.getId()) || (
                        StringUtils.isNotEmpty(tblRrRecordProjectMain.getId()) &&
                                !tblRrRecordProjectMain.getId().equals(rrRecordProjectMain.getId())
                ))) {
                    return "同个记账项目对应的[辅助项_营销工具]必须一致。";
                }
            }

        } catch (Exception e) {
            log.error("校验时查询出错", e);
            return "校验时查询出错";
        }
        return null;
    }

    @Override
    protected ObjectDataResponse insert(@RequestBody TblRrRecordProjectMain model, HttpServletRequest request) throws ServiceException {
        String message = checkSaveModel(model);
        if (StringUtils.isNotEmpty(message)) {
            return new ObjectDataResponse(ReturnStatusEnum.CHECK_FAILURE.getValue(), message);
        }
        return super.insert(model, request);
    }

    @Override
    protected ObjectDataResponse update(@RequestBody TblRrRecordProjectMain model, HttpServletRequest request) throws ServiceException {
        String message = checkUpdateModel(model);
        if (StringUtils.isNotEmpty(message)) {
            return new ObjectDataResponse(ReturnStatusEnum.CHECK_FAILURE.getValue(), message);
        }
        return super.update(model, request);
    }

    @Override
    public String verifyImportObject(TblRrRecordProjectMain tblRrRecordProjectMain, AnalysisContext analysisContext) {

        String message = super.verifyImportObject(tblRrRecordProjectMain, analysisContext);
        if (StringUtils.isNotEmpty(message)) {
            return message;
        }

        if (!StringUtils.isEmpty(tblRrRecordProjectMain.getChannelName())) {
            String channelNo = tblRrChannelService.getNoByName(tblRrRecordProjectMain.getChannelName());
            if (StringUtils.isEmpty(channelNo)) {
                return "渠道名称不正确:" + tblRrRecordProjectMain.getChannelName();
            }
            tblRrRecordProjectMain.setChannelNo(channelNo);
        }

        message = checkSaveModel(tblRrRecordProjectMain);
        if (StringUtils.isNotEmpty(message)) {
            return message;
        }

        return super.verifyImportObject(tblRrRecordProjectMain, analysisContext);
    }

    @Override
    protected String validateAllDate(List<TblRrRecordProjectMain> datas) {
        Map<String, String> channelNoBillTypeBillCategoryMap = new HashMap<>();
        for (TblRrRecordProjectMain data : datas) {
            String channelName = data.getChannelName();
            String billType = data.getBillType();
            String key = channelName + "_" + billType;

            String billCategoryInMap = channelNoBillTypeBillCategoryMap.get(key);
            if (StringUtils.isEmpty(billCategoryInMap)) {
                channelNoBillTypeBillCategoryMap.put(key, data.getBillCategory());
            } else {
                String billCategory = data.getBillCategory();
                if (!billCategory.equals(billCategoryInMap)) {
                    return "同个渠道+账单类型，必须是唯一的账单大类。渠道" +
                            channelName +
                            "+账单类型" +
                            billType +
                            "存在两个账单大类" +
                            CostAllocationEnum.BillCategoryEnum.getNameByNo(billCategory) +
                            "、" +
                            CostAllocationEnum.BillCategoryEnum.getNameByNo(billCategoryInMap);
                }
            }
        }

        boolean b = datas.stream()
                .collect(groupingBy(s-> StrUtil.nullToEmpty(s.getRecordAccountProject())))
                .entrySet().stream().map(
                        entry -> entry.getValue()
                                .stream()
                                .collect(groupingBy(s-> StrUtil.nullToEmpty(s.getNcMarketTool())))
                                .entrySet().size()
                ).anyMatch(size -> size > 1);
        if (b) {
            return "同个记账项目对应的[辅助项_营销工具]必须一致。";
        }

        List<String> list = new ArrayList<>();
        for (TblRrRecordProjectMain data : datas) {
            String toString = data.toString();
            if (list.contains(toString)) {
                return "有两行数据重复";
            } else {
                list.add(toString);
            }
        }

        return super.validateAllDate(datas);
    }
}

